/* 
	Default Event layout:
		function(){
			//event to run here
		}
*/
var tmp_v;
var tmp_f;
$(document).ready(function(){
	$(document.body).css({
		"background-color":"black",
		"color": "white"
	});
	c_stack.push($('body'));
	System.console = 0;
	System.output('Loading');
	System.versions['boot/Kernel.js'] = System.version;
	System.boot();
	System.version = System.versions['boot/Kernel.js'];
});
var System = {
	'defaults': {
		'slash': '',
		'name': 'Project Teal',
		'user': 'root'
	},
	'version': '0.0.7',
	'versions': {
		'boot/Kernel.js': ''
	},
	'support': function(r){
		return typeof window[r] != 'undefined';
	},
	'settings': {
		'load': function(name,obj){
			if(!File.type(File.path.cwd+'etc/'+name+'.set'))
				File.write(File.path.cwd+'etc/'+name+'.set','{}');
			var N = $.evalJSON(File.read(File.path.cwd+'etc/'+name+'.set'));
			$.extend(obj.defaults,N);
		},
		'save': function(name,obj){
			var j = $.toJSON(obj.defaults);
			File.write(File.path.cwd+'etc/'+name+'.set',j);
		}
	},
	'delete': function(o){
		if(typeof o =='string'){
			for(var p in window[o])
					delete window[o][p];
			window[o] = null;
			delete window[o];
		}
	},
	"event": {
		"runall": function(){
			while(e_stack.length){
				e = e_stack.pop();
				if(typeof e == 'function')
					e();
				else if(typeof e =="string")
					eval(e);
			}
		},
		"add": function(e){
			e_stack.push(e);
		}
	},
	'loadCSS': function(url,callback){
		var css = $("<link>").attr({
			rel:  "stylesheet",
			type: "text/css",
			href: url
		});
		$("head").append(css);
		if(callback)
			$(css).ready(callback);
	},
	"OS": '',
	"console": {},
	"output":function(r){
		c_stack[System.console].append(r);
	},
	"boot": function(){
		$('title').text(System.defaults.name);
		System.output('.');
		var system = navigator.appVersion;
		if (navigator.appVersion.indexOf("Mac") != -1 || navigator.appVersion.indexOf("PowerPC") != -1 ) system =  "Mac";
		else if (navigator.appVersion.indexOf("Win") != -1 ) system =  "Win";
		else if (navigator.appVersion.indexOf("SunOS") != -1 ) system =  "Solaris";
		else system =  "Linux";
		System.OS = system;
		System.output('.');
		var path = document.location;
		path = path+'';
		path = path.replaceAll('%20',' ');
		path = path.replaceAll('/','\\');
		path = path.substring(8,path.lastIndexOf("\\")+1); //chop off "file:///" and file name;
		if(System.OS!='Win')
			path = '/'+path;
		tmp_v = File.path.cwd = File.path.fix(path);
		System.output('.');
		if(System.OS=='Win')
			System.defaults.slash = '\\';
		else
			System.defaults.slash = '/';
		System.settings.load('system',System);
		File.path.cwd = File.path.fix(tmp_v);
		if(System.OS=='Win')
			System.defaults.slash = '\\';
		else
			System.defaults.slash = '/';
		System.settings.save('system',System);
		System.output('.<br/>');
		System.output('\u00A0\u00A0System OS: "'+System.OS+'"<br/>\u00A0\u00A0System Slash: "'+System.defaults.slash+'"<br/>\u00A0\u00A0System Directory: "'+File.path.cwd+'"<br/>Loading bin/');
		System.output(
			$('<div>')
				.attr('id','percent')
				.append('\u00A0\u00A0<span id="number">0</span>%')
		);
		System.output(
			$('<div>')
				.attr('id','message')
				.append('\u00A0\u00A0Listing Directory')
		);
		bin = File.ls(File.path.cwd+'/bin/');
		tmp_v = 0;
		tmp_f = function(){
			if(tmp_v+1!=bin.length){
				$("#number").html(Math.round((tmp_v+1)/bin.length*100));
				$("#message").html('\u00A0\u00A0'+bin[tmp_v+1]);
				tmp_v++;
				if(File.type(File.path.cwd+'bin/'+bin[tmp_v]) != 'css' && File.type(File.path.cwd+'bin/'+bin[tmp_v]) != 'dir')
					$.getScript('bin/'+bin[tmp_v],tmp_f);
				else if(File.type(File.path.cwd+'bin/'+bin[tmp_v]) == 'css')
					System.loadCSS('bin/'+bin[tmp_v],tmp_f);
				else
					setTimeout(tmp_f,1);
			}else{
				$("#number").html(100);
				e_stack.push(function(){
					t_stack.push({
						"name": 'EM',
						"description": 'Event Manager',
						"run": function(){
							System.event.runall();
						},
						"flags": {
							"running": true,
							"init": true,
							"interval": 1000
						},
						'time': new Date()
					});
					t_stack.push({
						"name": 'SYSTEM',
						"description": '',
						'end': function(){
							TM.close('TM');
							System.output('Restarting...<br/>');
							setTimeout(function(){
								window.location = window.location;
							},1000);
						},
						"flags": {
							"running": true,
							"init": true
						},
						'time': new Date()
					});
				});
				System.event.runall();
			}
		};
		$("#number").html(0);
		$("#message").html('\u00A0\u00A0'+bin[0]);
		if(File.type(File.path.cwd+'bin/'+bin[tmp_v]) != 'css' && File.type(File.path.cwd+'bin/'+bin[tmp_v]) != 'dir')
			$.getScript('bin/'+bin[tmp_v],tmp_f);
		else  if(File.type(File.path.cwd+'bin/'+bin[tmp_v]) == 'css')
			System.loadCSS('bin/'+bin[tmp_v],tmp_f);
		else
			setTimeout(tmp_f,1);
	},
	'install':function(){
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		var file = File.dialog.choose('Install Driver','driver');
		if(!file)
			return false;
		File.copy(file.path,File.path.cwd+'bin/');
	},
	// md5 script from http://www.webtoolkit.info/
	'md5': function (string) {
		function RotateLeft(lValue, iShiftBits) {
			return (lValue<<iShiftBits) | (lValue>>>(32-iShiftBits));
		}
		function AddUnsigned(lX,lY) {
			var lX4,lY4,lX8,lY8,lResult;
			lX8 = (lX & 0x80000000);
			lY8 = (lY & 0x80000000);
			lX4 = (lX & 0x40000000);
			lY4 = (lY & 0x40000000);
			lResult = (lX & 0x3FFFFFFF)+(lY & 0x3FFFFFFF);
			if (lX4 & lY4) {
				return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
			}
			if (lX4 | lY4) {
				if (lResult & 0x40000000) {
					return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
				} else {
					return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
				}
			} else {
				return (lResult ^ lX8 ^ lY8);
			}
		}
		function F(x,y,z) { return (x & y) | ((~x) & z); }
		function G(x,y,z) { return (x & z) | (y & (~z)); }
		function H(x,y,z) { return (x ^ y ^ z); }
		function I(x,y,z) { return (y ^ (x | (~z))); }
		function FF(a,b,c,d,x,s,ac) {
			a = AddUnsigned(a, AddUnsigned(AddUnsigned(F(b, c, d), x), ac));
			return AddUnsigned(RotateLeft(a, s), b);
		};
		function GG(a,b,c,d,x,s,ac) {
			a = AddUnsigned(a, AddUnsigned(AddUnsigned(G(b, c, d), x), ac));
			return AddUnsigned(RotateLeft(a, s), b);
		};
		function HH(a,b,c,d,x,s,ac) {
			a = AddUnsigned(a, AddUnsigned(AddUnsigned(H(b, c, d), x), ac));
			return AddUnsigned(RotateLeft(a, s), b);
		};
		function II(a,b,c,d,x,s,ac) {
			a = AddUnsigned(a, AddUnsigned(AddUnsigned(I(b, c, d), x), ac));
			return AddUnsigned(RotateLeft(a, s), b);
		};
		function ConvertToWordArray(string) {
			var lWordCount;
			var lMessageLength = string.length;
			var lNumberOfWords_temp1=lMessageLength + 8;
			var lNumberOfWords_temp2=(lNumberOfWords_temp1-(lNumberOfWords_temp1 % 64))/64;
			var lNumberOfWords = (lNumberOfWords_temp2+1)*16;
			var lWordArray=Array(lNumberOfWords-1);
			var lBytePosition = 0;
			var lByteCount = 0;
			while ( lByteCount < lMessageLength ) {
				lWordCount = (lByteCount-(lByteCount % 4))/4;
				lBytePosition = (lByteCount % 4)*8;
				lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount)<<lBytePosition));
				lByteCount++;
			}
			lWordCount = (lByteCount-(lByteCount % 4))/4;
			lBytePosition = (lByteCount % 4)*8;
			lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80<<lBytePosition);
			lWordArray[lNumberOfWords-2] = lMessageLength<<3;
			lWordArray[lNumberOfWords-1] = lMessageLength>>>29;
			return lWordArray;
		};
		function WordToHex(lValue) {
			var WordToHexValue="",WordToHexValue_temp="",lByte,lCount;
			for (lCount = 0;lCount<=3;lCount++) {
				lByte = (lValue>>>(lCount*8)) & 255;
				WordToHexValue_temp = "0" + lByte.toString(16);
				WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length-2,2);
			}
			return WordToHexValue;
		};
		function Utf8Encode(string) {
			string = string.replace(/\r\n/g,"\n");
			var utftext = "";
			for (var n = 0; n < string.length; n++) {
				var c = string.charCodeAt(n);
				if (c < 128) {
					utftext += String.fromCharCode(c);
				}
				else if((c > 127) && (c < 2048)) {
					utftext += String.fromCharCode((c >> 6) | 192);
					utftext += String.fromCharCode((c & 63) | 128);
				}
				else {
					utftext += String.fromCharCode((c >> 12) | 224);
					utftext += String.fromCharCode(((c >> 6) & 63) | 128);
					utftext += String.fromCharCode((c & 63) | 128);
				}
			}
			return utftext;
		};
		var x=Array();
		var k,AA,BB,CC,DD,a,b,c,d;
		var S11=7, S12=12, S13=17, S14=22;
		var S21=5, S22=9 , S23=14, S24=20;
		var S31=4, S32=11, S33=16, S34=23;
		var S41=6, S42=10, S43=15, S44=21;
		string = Utf8Encode(string);
		x = ConvertToWordArray(string);
		a = 0x67452301; b = 0xEFCDAB89; c = 0x98BADCFE; d = 0x10325476;
		for (k=0;k<x.length;k+=16) {
			AA=a; BB=b; CC=c; DD=d;
			a=FF(a,b,c,d,x[k+0], S11,0xD76AA478);
			d=FF(d,a,b,c,x[k+1], S12,0xE8C7B756);
			c=FF(c,d,a,b,x[k+2], S13,0x242070DB);
			b=FF(b,c,d,a,x[k+3], S14,0xC1BDCEEE);
			a=FF(a,b,c,d,x[k+4], S11,0xF57C0FAF);
			d=FF(d,a,b,c,x[k+5], S12,0x4787C62A);
			c=FF(c,d,a,b,x[k+6], S13,0xA8304613);
			b=FF(b,c,d,a,x[k+7], S14,0xFD469501);
			a=FF(a,b,c,d,x[k+8], S11,0x698098D8);
			d=FF(d,a,b,c,x[k+9], S12,0x8B44F7AF);
			c=FF(c,d,a,b,x[k+10],S13,0xFFFF5BB1);
			b=FF(b,c,d,a,x[k+11],S14,0x895CD7BE);
			a=FF(a,b,c,d,x[k+12],S11,0x6B901122);
			d=FF(d,a,b,c,x[k+13],S12,0xFD987193);
			c=FF(c,d,a,b,x[k+14],S13,0xA679438E);
			b=FF(b,c,d,a,x[k+15],S14,0x49B40821);
			a=GG(a,b,c,d,x[k+1], S21,0xF61E2562);
			d=GG(d,a,b,c,x[k+6], S22,0xC040B340);
			c=GG(c,d,a,b,x[k+11],S23,0x265E5A51);
			b=GG(b,c,d,a,x[k+0], S24,0xE9B6C7AA);
			a=GG(a,b,c,d,x[k+5], S21,0xD62F105D);
			d=GG(d,a,b,c,x[k+10],S22,0x2441453);
			c=GG(c,d,a,b,x[k+15],S23,0xD8A1E681);
			b=GG(b,c,d,a,x[k+4], S24,0xE7D3FBC8);
			a=GG(a,b,c,d,x[k+9], S21,0x21E1CDE6);
			d=GG(d,a,b,c,x[k+14],S22,0xC33707D6);
			c=GG(c,d,a,b,x[k+3], S23,0xF4D50D87);
			b=GG(b,c,d,a,x[k+8], S24,0x455A14ED);
			a=GG(a,b,c,d,x[k+13],S21,0xA9E3E905);
			d=GG(d,a,b,c,x[k+2], S22,0xFCEFA3F8);
			c=GG(c,d,a,b,x[k+7], S23,0x676F02D9);
			b=GG(b,c,d,a,x[k+12],S24,0x8D2A4C8A);
			a=HH(a,b,c,d,x[k+5], S31,0xFFFA3942);
			d=HH(d,a,b,c,x[k+8], S32,0x8771F681);
			c=HH(c,d,a,b,x[k+11],S33,0x6D9D6122);
			b=HH(b,c,d,a,x[k+14],S34,0xFDE5380C);
			a=HH(a,b,c,d,x[k+1], S31,0xA4BEEA44);
			d=HH(d,a,b,c,x[k+4], S32,0x4BDECFA9);
			c=HH(c,d,a,b,x[k+7], S33,0xF6BB4B60);
			b=HH(b,c,d,a,x[k+10],S34,0xBEBFBC70);
			a=HH(a,b,c,d,x[k+13],S31,0x289B7EC6);
			d=HH(d,a,b,c,x[k+0], S32,0xEAA127FA);
			c=HH(c,d,a,b,x[k+3], S33,0xD4EF3085);
			b=HH(b,c,d,a,x[k+6], S34,0x4881D05);
			a=HH(a,b,c,d,x[k+9], S31,0xD9D4D039);
			d=HH(d,a,b,c,x[k+12],S32,0xE6DB99E5);
			c=HH(c,d,a,b,x[k+15],S33,0x1FA27CF8);
			b=HH(b,c,d,a,x[k+2], S34,0xC4AC5665);
			a=II(a,b,c,d,x[k+0], S41,0xF4292244);
			d=II(d,a,b,c,x[k+7], S42,0x432AFF97);
			c=II(c,d,a,b,x[k+14],S43,0xAB9423A7);
			b=II(b,c,d,a,x[k+5], S44,0xFC93A039);
			a=II(a,b,c,d,x[k+12],S41,0x655B59C3);
			d=II(d,a,b,c,x[k+3], S42,0x8F0CCC92);
			c=II(c,d,a,b,x[k+10],S43,0xFFEFF47D);
			b=II(b,c,d,a,x[k+1], S44,0x85845DD1);
			a=II(a,b,c,d,x[k+8], S41,0x6FA87E4F);
			d=II(d,a,b,c,x[k+15],S42,0xFE2CE6E0);
			c=II(c,d,a,b,x[k+6], S43,0xA3014314);
			b=II(b,c,d,a,x[k+13],S44,0x4E0811A1);
			a=II(a,b,c,d,x[k+4], S41,0xF7537E82);
			d=II(d,a,b,c,x[k+11],S42,0xBD3AF235);
			c=II(c,d,a,b,x[k+2], S43,0x2AD7D2BB);
			b=II(b,c,d,a,x[k+9], S44,0xEB86D391);
			a=AddUnsigned(a,AA);
			b=AddUnsigned(b,BB);
			c=AddUnsigned(c,CC);
			d=AddUnsigned(d,DD);
		}
		var temp = WordToHex(a)+WordToHex(b)+WordToHex(c)+WordToHex(d);
		return temp.toLowerCase();
	},
};
var bin = new Array();
var c_stack = new Array();
var e_stack = new Array();
var t_stack = new Array();
var File = {
	'dialog':{
		'choose':function(title,type){
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
			const nsIFilePicker = Components.interfaces.nsIFilePicker;
			var fp = Components.classes["@mozilla.org/filepicker;1"]
						   .createInstance(nsIFilePicker);
			fp.init(window, title, nsIFilePicker.modeOpen);
			switch(type){
				case 'app':
					fp.appendFilter("Teal App","*.ta3;");
				break;
				case 'driver':
					fp.appendFilter("Teal Driver","*.td3;");
				break;
				case 'image':
					fp.appendFilters(0x008);
				break;
			}
			fp.appendFilters(nsIFilePicker.filterAll);
			var rv = fp.show();
			if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) {
				var file = fp.file;
				// Get the path as string. Note that you usually won't
				// need to work with the string paths.
				var path = fp.file.path;
				// work with returned nsILocalFile...
				return file;
			}
		},
		'store':function(title){
			var nsIFilePicker = Components.interfaces.nsIFilePicker;
			var fileChooser = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
			fileChooser.init(window, title,nsIFilePicker.modeSave);
			fileChooser.appendFilters( nsIFilePicker.filterAll);
			var fileBox = fileChooser.show();
			if (fileBox == nsIFilePicker.returnOK || nsIFilePicker.returnReplace) {
				var returnfile = fileChooser.file;
				var returnpath = fileChooser.file.path;
			}
			return returnfile;
		}
	},
	'read': function(path) {
		path = File.path.fix(path);
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			alert("Permission to read file was denied.");
		}
		var file = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath( path );
		if ( file.exists() == false ) {
			return false;
		}
		var is = Components.classes["@mozilla.org/network/file-input-stream;1"]
			.createInstance( Components.interfaces.nsIFileInputStream );
		is.init( file,0x01, 00004, null);
		var sis = Components.classes["@mozilla.org/scriptableinputstream;1"]
			.createInstance( Components.interfaces.nsIScriptableInputStream );
		sis.init( is );
		var output = sis.read( sis.available() );
		sis.close();
		return output;
	},
	'write': function(path,string,type){
		//type 0x02 | 0x08 | 0x20 overwrites
		//type 0x02 | 0x10 appends
		path = File.path.fix(path);
		if(!type)
			type = 0x02 | 0x08 | 0x20;
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			return false;
		}
		var file = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath(path);
		if ( file.exists() == false ) {
			file.create( Components.interfaces.nsIFile.NORMAL_FILE_TYPE, 420 );
		}
		var outputStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
			.createInstance( Components.interfaces.nsIFileOutputStream );
		/* Open flags 
		#define PR_RDONLY       0x01
		#define PR_WRONLY       0x02
		#define PR_RDWR         0x04
		#define PR_CREATE_FILE  0x08
		#define PR_APPEND      0x10
		#define PR_TRUNCATE     0x20
		#define PR_SYNC         0x40
		#define PR_EXCL         0x80
		*/
		/*
		** File modes ....
		**
		** CAVEAT: 'mode' is currently only applicable on UNIX platforms.
		** The 'mode' argument may be ignored by PR_Open on other platforms.
		**
		**   00400   Read by owner.
		**   00200   Write by owner.
		**   00100   Execute (search if a directory) by owner.
		**   00040   Read by group.
		**   00020   Write by group.
		**   00010   Execute by group.
		**   00004   Read by others.
		**   00002   Write by others
		**   00001   Execute by others.
		**
		*/
		outputStream.init( file, type, 420, 0 );
		try{
			outputStream.write( string, string.length );
			outputStream.close();
		} catch (e){
			return false;
		}
		return file;
	},
	'move': function (path,path2){
		path = File.path.fix(path);
		path2 = File.path.fix(path2);
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");


		} catch (e) {
			return false;
		}
		var file = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath( path );
		if(file.isDirectory()){
			if(path.lastIndexOf(System.defaults.slash)+1!=path.length)
				var path3 = path.substring(0,path.lastIndexOf(System.defaults.slash)+1);
			else{
				var path3 = path.substring(0,path.length-1);
				path3 = path3.substring(0,path3.lastIndexOf(System.defaults.slash)+1);
			}
		}else
			var path3 = path.substring(0,path.lastIndexOf(System.defaults.slash)+1);
		var file2 = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file2.initWithPath( path3 );
		if ( file.exists() == false ) {
			return false;
		}
		if(file.isDirectory()){
			if(path2.lastIndexOf(System.defaults.slash)+1!=path2.length)
				var name = path2.substring(path2.lastIndexOf(System.defaults.slash)+1,path2.length);
			else{
				path2 = path2.substring(0,path2.length-1);
				var name = path2.substring(path2.lastIndexOf(System.defaults.slash)+1,path2.length);
			}
		}else
			var name = path2.substring(path2.lastIndexOf(System.defaults.slash)+1,path2.length);
		try{
			file.moveTo(file2,name);
			return true;
		}catch(e){
			return false;
		}
	},
	'copy': function(path,path2){
		path = File.path.fix(path);
		path2 = File.path.fix(path2);
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			return false;
		}
		var file = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath( path );
		var file2 = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file2.initWithPath( path2 );
		if ( file.exists() == false ) {
			return false;
		}
		try{
			file.copyTo(file2,file.leafName);
		}catch(e){
			return false;
		}
		return true;
	},
	'rename': function(path,name){
		path = File.path.fix(path);
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			return false;
		}
		var file = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath( path );
		if(file.isDirectory()){
			if(path.lastIndexOf(System.defaults.slash)+1!=path.length)
				path = path.substring(0,path.lastIndexOf(System.defaults.slash)+1);
			else{
				path = path.substring(0,path.length-1);
				path = path.substring(0,path.lastIndexOf(System.defaults.slash)+1);
			}
		}else
			path = path.substring(0,path.lastIndexOf(System.defaults.slash)+1);
		var dir = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		dir.initWithPath( path );
		if ( file.exists() == false ) {
			return false;
		}
		try{
			file.moveTo(dir,name);
			return true;
		}catch(e){
			return false;
		}
	},
	'delete': function(path){
		path = File.path.fix(path);
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			return false;
		}
		var file = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath(path);
		try{
			file.remove(file);
			return true;
		}catch(e){
			return false;
		}
	},
	'mkdir': function(path,options){
		path = File.path.fix(path);
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			return false;
		}
		var file = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath(path);
		if(!options)
			options = 0775;
		if ( file.exists() == false ) {
			try{
				file.create( Components.interfaces.nsIFile.DIRECTORY_TYPE, options );
				return true;
			}catch(e){
				return false;
			}
		}else
			return false;
	},
	'ls': function(path){
		netscape.security.PrivilegeManager.enablePrivilege('UniversalXPConnect');
		path = File.path.fix(path);
		var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath(path);
		var entries = file.directoryEntries;
		var array = new Array();
		while(entries.hasMoreElements()){
			var entry = entries.getNext();
			entry.QueryInterface(Components.interfaces.nsIFile);
			var thePath = entry.path;
			if(System.OS == 'Win')
				thePath = thePath.substring(1+thePath.lastIndexOf('\\'));
			else
				thePath = thePath.substring(1+thePath.lastIndexOf('/'));
			if(thePath!='.directory'){
				array.push(thePath);
			}
		}
		return array;
	},
	'path':{
		'fix': function(path){
			// determine the file-separator
			if (System.defaults.slash=='\\')
				return path.replaceAll('/','\\');
			else
				return path.replaceAll('\\','/');
		},
		"cwd": '',
		"of": function(p){
			p = File.path.fix(p);
			return p.substring(0,p.lastIndexOf(System.defaults.slash))
		}
	},
	"type": function(path){
		path = File.path.fix(path);
		try {
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		} catch (e) {
			return false;
		}
		var file = Components.classes["@mozilla.org/file/local;1"]
			.createInstance(Components.interfaces.nsILocalFile);
		file.initWithPath(path);
		if(!file.exists())
			return false;
		if(file.isDirectory())
			return 'dir';
		else if(file.isFile()){
			path = path.replace(/^.*\\/, '')
			return (((/[.]/.exec(path)) ? /[^.]+$/.exec(path) : 'file')+'').toLowerCase();
		}else
			return false;
	},
	"get": function(url,path,p,c){
		path = File.path.fix(path);
		File.mkdir(File.path.of(path));
		netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
		var r = true;
		try {			
			//new obj_URI object
			var obj_URI = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService).newURI(url, null, null);

			//new file object
			var obj_TargetFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);

			//set file with path
			obj_TargetFile.initWithPath(path);
			//if file doesn't exist, create
			if(!obj_TargetFile.exists()) {
				obj_TargetFile.create(0x00,0644);
			}

			//new persitence object
			var obj_Persist = Components.classes["@mozilla.org/embedding/browser/nsWebBrowserPersist;1"].createInstance(Components.interfaces.nsIWebBrowserPersist);

			// with persist flags if desired
			const nsIWBP = Components.interfaces.nsIWebBrowserPersist;
			const flags = nsIWBP.PERSIST_FLAGS_REPLACE_EXISTING_FILES;
			obj_Persist.persistFlags = flags | nsIWBP.PERSIST_FLAGS_FROM_CACHE;


			//save file to target
			obj_Persist.saveURI(obj_URI,null,null,null,null,obj_TargetFile);
			if(typeof c!='function')
				c = function(){};
			if(typeof p!='function')
				p = function(){};
			(function(c,p){
				obj_Persist.progressListener = {
					onProgressChange: p,
					onStateChange: function(aWebProgress, aRequest, aFlag, aStatus){
						if(aFlag & 0x00000010)
							c(aWebProgress, aRequest, aFlag, aStatus);
					}
				};
			})(c,p);
		} catch (e) {
			r = false;
		}
		return r;
	}
};
// Replaces all instances of the given substring.
String.prototype.replaceAll = function(strTarget,strSubString){
	var strText = this;
	var intIndexOfMatch = strText.indexOf( strTarget );
	 
	// Keep looping while an instance of the target string
	// still exists in the string.
	while (intIndexOfMatch != -1){
		// Relace out the current instance.
		strText = strText.replace( strTarget, strSubString )
		 
		// Get the index of any next matching substring.
		intIndexOfMatch = strText.indexOf( strTarget );
	}
	 
	// Return the updated string with ALL the target strings
	// replaced out with the new substring.
	return( strText );
}
$.fn.extend({
	// keep text from being selected on specified items
	disableSelection: function() { 
		this.each(function() { 
			if (typeof this.onselectstart != 'undefined') {
				this.onselectstart = function() { return false; };
			} else if (typeof this.style.MozUserSelect != 'undefined') {
				this.style.MozUserSelect = 'none';
			} else {
				this.onmousedown = function() { return false; };
			}
		}); 
	}
});
